﻿using System;
using System.Diagnostics;
using System.Text;
using RabbitMQDemo.Common;

namespace RabbitMQDemo.Producer
{
    public class Transaction
    {
        private const string ExchangeName = "trans_exchange";

        private const string QueueName = "trans_queue";

        private const string RoutingKey = "trans_routing";

        public static void Send(string[] args)
        {
            var isError = Utils.GetFirstValue(args) == 0;

            using var connection = MQClient.GetConnection();
            using var channel = connection.CreateModel();

            // 声明交换机
            channel.ExchangeDeclare(exchange: ExchangeName, type: "direct", durable: false, autoDelete: false, arguments: null);

            // 声明队列
            channel.QueueDeclare(queue: QueueName, durable: false, exclusive: false, autoDelete: false, arguments: null);
            channel.QueueBind(queue: QueueName, exchange: ExchangeName, routingKey: RoutingKey, arguments: null);

            var sw = new Stopwatch();
            sw.Start();

            try
            {
                // 开启事务
                channel.TxSelect();

                var index = 0;
                while (index < 10)
                {
                    // 发送消息
                    channel.BasicPublish(exchange: ExchangeName, routingKey: RoutingKey, mandatory: false, basicProperties: null, body: GetMessage(index));

                    // Thread.Sleep(1000);
                    Console.WriteLine("Send trans message");
                    index++;

                    if (isError && index > 5)
                    {
                        throw new Exception("errmsg");
                    }
                }

                channel.TxCommit();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"error: {ex.Message}");
                if (channel.IsOpen)
                {
                    channel.TxRollback();
                }
            }

            sw.Stop();
            Console.WriteLine($"over. ElapsedMilliseconds={sw.ElapsedMilliseconds}");
        }

        private static byte[] GetMessage(int? i = null) => Encoding.UTF8.GetBytes($"[Trans]{(i.HasValue ? $"[{i}]" : string.Empty)} message");
    }
}
